﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Kokomo.Mirror.CliMetadata;

namespace Kokomo.PeInspector.Reflection.Disassembly
{
	/// <summary>
	/// Represents a dependency on a type from MSIL.
	/// </summary>
	public class MsilTypeDependency : MsilMemberDependency
	{
		public Type GetTypeDependency()
		{
			return (Type)this.GetMemberDependency();
		}

		/// <summary>
		/// Gets the usage of <see cref="Type"/>.
		/// </summary>
		/// <seealso cref="MsilTypeUsage"/>
		public MsilTypeUsage Usage { get; private set; }

		/// <summary>
		/// Initializes a new instance of <see cref="MsilTypeDependency"/>.
		/// </summary>
		/// <param name="offset">The offset of the instruction causing the dependency.</param>
		/// <param name="type">The type dependency.</param>
		/// <param name="usage">The usage of the type.</param>
		/// <seealso cref="MsilTypeUsage"/>
		private MsilTypeDependency(
			Module targetModule,
			int metadataToken,
			MsilTypeUsage usage,
			int offset
			)
			: base(targetModule, metadataToken, offset)
		{
			this.Usage = usage;
		}

		public static MsilTypeDependency FromType(
			Type type,
			MsilTypeUsage usage,
			int offset = 0
			)
		{
			if (type == null) throw new ArgumentNullException("type");
			return new MsilTypeDependency(type.Module, type.MetadataToken, usage, offset);
		}
		public static MsilTypeDependency FromTypeRef(
			ModuleMemberReference typeRef,
			MsilTypeUsage usage,
			int offset = 0
			)
		{
			if (ModuleMemberReference.IsEmpty(typeRef)) throw new ArgumentNullException("typeRef");
			return new MsilTypeDependency(typeRef.Module, typeRef.MetadataToken, usage, offset);
		}
	}
}
